package org.melanesia.converters.java;

import org.melanesia.converters.JavaToJavaConverter;
import org.melanesia.converters.TypeConverter;

/**
 * Converts string representation of boolean value into a true / false
 * representation.
 *
 * The constructor of this class takes an array of strings as an argiment. This
 * array defines string values, that will be converted to boolean
 * <code>true</code>.
 *
 * Any other value is converted into false.
 *
 * Note, that the array may contain <code>null</code>. In such case, the null
 * value is also converted to <code>true</code>.
 *
 * The <code>yesValues</code> are compared case sensitive or insensitive,
 * depending on the value of <code>ignoreCase</code> in
 * {@link #StringToBooleanConverter(boolean, String...)}. The default value for
 * <code>ignoreCase</code>, when instantiated using
 * {@link #StringToBooleanConverter(String...)} is <code>false</code>.
 *
 * @author marcin.kielar
 *
 */
public class StringToBooleanConverter extends JavaToJavaConverter {

    /**
     * Should the case be ignored when comparing converted value with
     * <code>yesValues</code>.
     */
    private final boolean ignoreCase;

    /** Values converted to boolean <code>true</code>. */
    private final String[] yesValues;

    /**
     * Constructs string to boolean converter. <code>yesValues</code> will be
     * converted to "true". Other values will be converted to false.
     *
     * The values will be compared case sensitive.
     *
     * @param yesValues
     *            list of values that should be converted to boolean
     *            <code>true</code>
     */
    public StringToBooleanConverter(final String... yesValues) {
        this(true, yesValues);
    }

    /**
     * Constructs string to boolean converter. <code>yesValues</code> will be
     * converted to "true". Other values will be converted to false.
     *
     * @param ignoreCase
     *            if true, this converter will compare <code>yesValues</code>
     *            ignoring case
     * @param yesValues
     *            list of values that should be converted to boolean
     *            <code>true</code>
     */
    public StringToBooleanConverter(final boolean ignoreCase, final String... yesValues) {
        this.ignoreCase = ignoreCase;
        this.yesValues = yesValues;
    }

    @Override
    public final Object convert(final TypeConverter typeConverterContext, final Object value) {

        for (String yesValue : yesValues) {
            if ((yesValue == null && value == null)
                    || (ignoreCase && yesValue.equalsIgnoreCase((String) value))
                    || (yesValue.equals(value))) {
                return true;
            }
        }

        return false;
    }
}
